package com.tim.util;

import org.apache.commons.lang3.StringUtils;
import org.jsoup.internal.StringUtil;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 分析字符串，获取内容
 * @author Administrator
 *
 */
public class StringAnalysisUtil {
	/**
	 * 帕斯卡命名法
	 * 	cu_event_info => CuEventInfo
	 */
	public static String toPascal(String str) {//首字母转大写
		str = toCamel(str);
		str = head2UpperCase(str);
//		System.out.println(className);
		return str;
	}

	/**
	 * 转驼峰命名法；
	 * 	cu_event_info => cuEventInfo 
	 */
	public static String toCamel(String str) {
		//下划线转大写
		if(str.contains("_")) {
			String regex = "(_[a-z])";
			Matcher matcher = Pattern.compile(regex).matcher(str);
			while(matcher.find()) {
				String group = matcher.group(1);
				str = str.replace(group, group.toUpperCase().substring(1));
			}
		}
		str = head2LowerCase(str);
		return str;
	}
	
	/**
	 * 转回下划线命名法
	 * 	CuEventInfo => cu_event_info
	 */
	public static String back2Subline(String str) {
		if(StringUtils.isBlank(str)){
			return str;
		}
		// 首字符转小写
		str = head2LowerCase(str);
		// 大写字母转下划线
		String regex = "([A-Z])";
		Matcher matcher = Pattern.compile(regex).matcher(str);
		while(matcher.find()) {
			String group = matcher.group(1);
			str = str.replace(group, "_"+group.toLowerCase());
		}
		return str;
	}
	/**
	 * 首字母转大写
	 */
	public static String head2UpperCase(String str){
		if(StringUtil.isBlank(str)){
			return str;
		}
		str = str.trim();
		str = Character.toUpperCase(str.charAt(0))+str.substring(1);
		return str;
	}
	/**
	 * 首字母转小写
	 */
	public static String head2LowerCase(String str){
		if(StringUtil.isBlank(str)){
			return str;
		}
		str = str.trim();
		str = Character.toLowerCase(str.charAt(0))+str.substring(1);
		return str;
	}

	/**
	 * 获取注解内容，即双引号内内容<br/>
	 * 	@Param("事件标题") => 事件标题
	 */
	public static String getAnnoValue(String annoLine){
		return getAnnoValue(annoLine, "value");
	}

	/**
	 * 获取注解内容，即双引号内内容<br/>
	 * 	@Param("事件标题") => 事件标题
	 */
	public static String getAnnoValue(String annoLine, String attrName){
		if(StringUtil.isBlank(annoLine)){
			return annoLine;
		}
		int loc = annoLine.indexOf(attrName);
//		loc = loc==-1 ? 0 : loc;
		if(loc==-1 && !"value".equals(attrName)){
			return null;
		}
		int start = annoLine.indexOf('"', loc);
		if(start==-1){
			return "";
		}
		int end = annoLine.indexOf('"', ++start);
		return annoLine.substring(start, end);
	}
	
	/**
	 * 按属性声明行获取属性名<br/>
	 * 	private String startTime; => startTime
	 */
	public static String getFieldName(String fieldLine){
		if(StringUtil.isBlank(fieldLine)){
			return fieldLine;
		}
		return getFieldInfo(fieldLine)[2];
	}
	
	/**
	 * 按属性声明行获取属性信息<br/>
	 * 	private String startTime; => {private, String, startTime}
	 */
	public static String[] getFieldInfo(String fieldLine){
		if(StringUtil.isBlank(fieldLine)){
			return null;
		}
		// 去除修饰词
		List<String> modifyWords = Arrays.asList("static ", "final ", 
				"transient ", "volatile ");
		for (String word : modifyWords) {
			fieldLine.replace(word, "");
		}
		String[] strs = fieldLine.trim().replaceAll("\\s+", " ").split("\\s");
		String fieldName = strs[2].replace(";", "");
		
		return new String[]{strs[0], strs[1], fieldName};
	}
	
	/**
	 * 获取属性名列表
	 */
	public static List<String> getFieldNameList(String code) {
		if (StringUtil.isBlank(code)) {
			return Collections.emptyList();
		}
		return Arrays.stream(code.split("\n"))
				.map(String::trim)
				.filter(item -> item.startsWith("private"))
				.map(StringAnalysisUtil::getFieldName)
				.filter(StringUtils::isNotBlank)
				.collect(Collectors.toList());
	}
	
	/**
	 * 获取属性信息列表
	 */
	public static List<String[]> getFieldInfoList(String code) {
		if (StringUtil.isBlank(code)) {
			return Collections.emptyList();
		}
		return Arrays.stream(code.split("\n"))
				.map(String::trim)
				.filter(item -> item.startsWith("private"))
				.map(StringAnalysisUtil::getFieldInfo)
				.filter(Objects::nonNull)
				.collect(Collectors.toList());
	}

	/** 分析方法签名信息<br/>
	 * 	public String hello(String a); => {String, hello, String a}
	 */
	public static String[] getMethodInfo(String code) {
		try {
			int firstQuoteIndex = code.indexOf("(");
			if(firstQuoteIndex==-1){
				return null;
			}
			String preStr = code.substring(0, firstQuoteIndex).trim();
			String argInfo = code.substring(firstQuoteIndex+1, code.lastIndexOf(")")).trim();
			String[] strs = preStr.trim().split("\\s+");
			return new String[]{strs[strs.length-2], strs[strs.length-1], argInfo};
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**   
	 *@describe 按回车分隔，并剔除空行；trim
	 *@author Tim
	 *@create 2021/6/7 11:18
	 */       
	public static List<String> splitByEnter(String str){
		if(StringUtils.isBlank(str)){
			return Collections.emptyList();
		}
		return Arrays.stream(str.split("\n"))
				.filter(StringUtils::isNotBlank)
				.map(String::trim)
				.collect(Collectors.toList());
	}

	/**分析java文件；返回包名、类名、body*/
	public static List<String> getClassInfo(String path, boolean hasStatic){
		String packageName="", className="", content = "";
		try {
			String[] pathInfos = path.split("[\\\\/]+");
			String pathInfo = pathInfos[pathInfos.length-1];
			className = pathInfo.substring(0, pathInfo.lastIndexOf("."));
			List<String> list = Files.readAllLines(Paths.get(path));
			for (int i = 0; i < list.size(); i++) {
				String line = list.get(i);
				if(line.trim().startsWith("package")){
					packageName = line.replaceAll("package", "")
							.replaceAll("[\\s;]", "");
				}
				if(line.contains(" class") || line.contains(" interface")){
					list = list.subList(i+1, list.size());
					break;
				}
			}
			content = list
					.stream()
					.filter(item->StringUtils.isNotBlank(item) && ( hasStatic || !item.contains(" static ")))
					.collect(Collectors.joining("\n"))
					.replaceAll("}", "");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return Arrays.asList(packageName, className, content);
	}

	public static boolean notMethodSignature(String code) {
		code = code.trim().replaceAll("\\s+", " ");
		return code.length()<10
				|| code.startsWith("*")
				|| code.startsWith("/")
				|| code.startsWith("@");
	}

	/**
	 * 简单处理注释信息
	 */
	public static String getComment(String line){
		if(StringUtils.isBlank(line)){
			return "";
		}
		String comment = line.trim()
				.replaceAll("^/\\*+", "")
				.replaceAll("\\*/$", "")
				.replaceAll("^\\*\\s*", "")
				.replaceAll("^//\\s*", "")
				.replaceAll("@\\w+", "");
		return comment.matches("[\\w\\.><\\s]+") ? "" : comment;
	}

	public static void main(String[] args) {
		System.out.println(toPascal("cu_event_info"));
		System.out.println(toCamel("cu_event_info"));
		System.out.println(back2Subline("CuEventInfo"));
	}
	
}
